<!DOCTYPE html>
<html lang="zh-CN">

  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>业务账号绑定</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css">
    <script src="https://cdn.jsdmirror.com/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://cdn.jsdmirror.com/npm/axios@0.27.2/dist/axios.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <!-- 自定义样式 -->
    <link rel="stylesheet" href="/styles/common.css">
  </head>

  <body>
    <div id="app" class="container">
      <div class="card-wrapper">
        <!-- 微信用户信息卡片（已授权状态） -->
        <div class="card fade-in" style="animation-delay: 0.1s">
          <h1 class="desktop-title">业务账号绑定</h1>
          <div class="user-info">
            <div class="user-info__avatar">
              <img :src="userInfo.headimgurl||'/images/NotFound.png'" alt="用户头像" />
            </div>
            <div class="user-info__detail">
              <div class="user-info__name" v-if="isAuthorized">
                {{userInfo.nickname}}
              </div>
              <div class="user-info__name" style="cursor: pointer" @click="showAuthDialog=true" v-else>
                请先授权微信账号
              </div>
              <div class="user-info__wechat">微信绑定信息</div>
              <div class="user-info__openid" v-if="isAuthorized">
                手机号{{userInfo.phone ? ': ' + userInfo.phone : '暂未绑定'}}
              </div>
            </div>
          </div>
          <div class="info-tip" v-if="!isAuthorized||!userInfo.phone">
            <i class="fa fa-info-circle"></i>
            <span>
              请完善以下信息完成业务账号绑定，以便接收报告发送、项目进度查询等通知
            </span>
          </div>
        </div>

        <!-- 表单卡片 -->
        <div class="card fade-in" style="animation-delay: 0.2s">
          <el-form ref="bindingForm" label-position="top" :model="formData" :rules="formRules" :disabled="!isAuthorized"
            label-width="100px" class="binding-form">
            <!-- 角色选择 -->
            <el-form-item label="角色类型" prop="role" class="form-item">
              <div class="role-group">
                <div class="role-item"
                  :class="{ active: formData.role === 'inspected', disabled: !isAuthorized || completeBinding }"
                  @click="(isAuthorized && !completeBinding) && (formData.role = 'inspected')">
                  <i class="el-icon-school"></i>
                  <div class="role-item__text">受检单位</div>
                </div>
                <div class="role-item"
                  :class="{ active: formData.role === 'entrusted', disabled: !isAuthorized || completeBinding }"
                  @click="(isAuthorized && !completeBinding) && (formData.role = 'entrusted')">
                  <i class="el-icon-office-building"></i>
                  <div class="role-item__text">委托单位</div>
                </div>
                <div class="role-item"
                  :class="{ active: formData.role === 'technician', disabled: !isAuthorized || completeBinding }"
                  @click="(isAuthorized && !completeBinding) && (formData.role = 'technician')">
                  <i class="el-icon-first-aid-kit"></i>
                  <div class="role-item__text">检测机构技术服务人员</div>
                </div>
              </div>
            </el-form-item>

            <!-- 企业选择下拉框，仅当选择受检单位或委托单位时显示 -->
            <el-form-item v-if="!completeBinding && (formData.role === 'inspected' || formData.role === 'entrusted')"
              :label="formData.role === 'inspected' ? '受检企业' : '委托企业'" prop="enterpriseId" class="form-item">
              <el-select v-model="formData.enterpriseId" filterable remote clearable reserve-keyword style="width: 100%"
                placeholder="请输入企业名称搜索" :remote-method="handleRemoteSearch" :loading="enterpriseLoading"
                :disabled="!isAuthorized" @clear="handleEnterpriseClear">
                <el-option v-for="enterprise in enterpriseOptions" :key="enterprise._id" :label="enterprise.cname"
                  :value="enterprise._id">
                  {{ enterprise.cname }}
                </el-option>
              </el-select>
            </el-form-item>

            <!-- 手机号 -->
            <el-form-item label="手机号码" prop="phone" class="form-item">
              <el-input v-model="formData.phone" placeholder="请输入手机号码" maxlength="11" @input="handlePhoneInput"
                :disabled="!isAuthorized || completeBinding"></el-input>
            </el-form-item>

            <!-- 验证码 -->
            <el-form-item v-if="!completeBinding" label="验证码" prop="code" class="form-item">
              <div class="verify-code">
                <el-input v-model="formData.code" placeholder="请输入验证码" maxlength="6"
                  :disabled="!isAuthorized"></el-input>
                <el-button type="primary" :disabled="!canSendCode || isSendingCode || !isAuthorized"
                  @click="sendVerificationCode">
                  <span v-if="!isSendingCode">{{ codeText }}</span>
                  <span v-if="isSendingCode">
                    <i class="el-icon-loading"></i> 发送中
                  </span>
                </el-button>
              </div>
            </el-form-item>

            <!-- 提交按钮 -->
            <el-form-item v-if="!completeBinding" class="form-actions">
              <el-button type="primary" class="submit-btn" @click="submitForm" :loading="isSubmitting"
                :disabled="!isAuthorized">
                完成绑定
              </el-button>
            </el-form-item>
          </el-form>
          <el-button type="primary" class="submit-btn" v-if="isAuthorized && completeBinding"
            @click="completeBinding = false">
            重新绑定
          </el-button>
        </div>
      </div>

      <!-- 未授权弹窗 -->
      <el-dialog center width="300px" title="微信授权" class="custom-round-dialog" :visible.sync="showAuthDialog"
        :close-on-click-modal="false" :lock-scroll="true" :modal="true">
        <div class="auth-dialog-content">
          <div class="auth-icon">
            <i class="fa fa-weixin"></i>
          </div>
          <div class="auth-title">需要微信授权</div>
          <div class="auth-desc">
            请授权获取微信账号信息，以便完成业务账号绑定及接收相关通知
          </div>
        </div>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" class="auth-btn" @click="startAuthorization">
            立即授权
          </el-button>
        </div>
      </el-dialog>
    </div>
    <script>
      new Vue({
        el: "#app",
        data() {
          // 手机号验证规则
          const validatePhone = (rule, value, callback) => {
            if (!value) {
              return callback(new Error("请输入手机号码"));
            }
            const reg = /^1[3-9]\d{9}$/;
            if (!reg.test(value)) {
              return callback(new Error("请输入正确的手机号码"));
            }
            callback();
          };

          // 验证码验证规则
          const validateCode = (rule, value, callback) => {
            if (!value) {
              return callback(new Error("请输入验证码"));
            }
            const reg = /^\d{6}$/;
            if (!reg.test(value)) {
              return callback(new Error("请输入6位数字验证码"));
            }
            callback();
          };

          // 企业选择验证规则
          const validateEnterprise = (rule, value, callback) => {
            if (!value) {
              return callback(new Error("请选择企业"));
            }
            callback();
          };
          return {
            // 加载与授权状态
            isAuthorized: false, // 新增：授权状态标记
            isSubmitting: false,
            isSendingCode: false,
            showAuthDialog: false,
            completeBinding: false,
            activeRouter: "/",
            code: "",

            enterpriseOptions: [],
            enterpriseLoading: false,
            searchTimer: null,

            // 微信授权信息
            authConfig: {
              // 授权服务器地址
              authServerUrl:
                "https://open.weixin.qq.com/connect/oauth2/authorize",
              // 应用ID
              appId: "<%=appId%>",
              // 应用授权作用域，snsapi_base （不弹出授权页面，直接跳转，只能获取用户openid），snsapi_userinfo （弹出授权页面，可通过openid拿到昵称、性别、所在地。并且， 即使在未关注的情况下，只要用户授权，也能获取其信息 ）
              scope: "snsapi_base",
              // 响应类型，通常是code
              responseType: "code",
            },

            // 用户信息
            userInfo: {
              nickname: "",
              headimgurl: "",
              phone: "",
              openid: "",
            },

            // 表单数据
            formData: {
              role: "",
              phone: "",
              code: "",
              enterpriseId: "",
            },

            // 表单验证规则
            formRules: {
              role: [
                {
                  required: true,
                  message: "请选择角色类型",
                  trigger: "change",
                },
              ],
              enterpriseId: [
                {
                  required: true,
                  validator: validateEnterprise,
                  trigger: "change",
                },
              ],
              phone: [
                {
                  required: true,
                  validator: validatePhone,
                  trigger: ["blur", "change"],
                },
              ],
              code: [
                {
                  required: true,
                  validator: validateCode,
                  trigger: ["blur", "change"],
                },
              ],
            },

            // 验证码相关
            codeText: "发送验证码",
            countdown: 60,
          };
        },
        watch: {
          // 角色改变时清除企业选择
          "formData.role"(newVal) {
            if (newVal !== "inspected" && newVal !== "entrusted") {
              this.formData.enterpriseId = "";
              this.enterpriseOptions = [];
            }
          },
        },
        beforeDestroy() {
          // 清除定时器
          clearTimeout(this.searchTimer);
        },
        computed: {
          // 是否可以发送验证码
          canSendCode() {
            return /^1[3-9]\d{9}$/.test(this.formData.phone);
          },
        },
        mounted() {
          this.activeRouter = window.location.pathname;
          // 检查是否已有授权信息
          this.checkAuthorizationCallback();
        },
        methods: {
          // 返回上一页
          goBack() {
            window.history.back();
          },
          // 远程搜索企业
          handleRemoteSearch(query) {
            // 清除之前的定时器
            clearTimeout(this.searchTimer);
            // 防抖处理
            this.searchTimer = setTimeout(async () => {
              if (query.trim() === "") {
                this.enterpriseOptions = [];
                return;
              }

              this.enterpriseLoading = true;
              try {
                const response = await axios.get(
                  "/api/getCompany?keyword=" + query
                );
                this.enterpriseOptions = response.data.data || [];
              } catch (error) {
                this.$message.error("企业搜索失败，请稍后重试");
                console.error("企业搜索错误:", error);
                this.enterpriseOptions = [];
              } finally {
                this.enterpriseLoading = false;
              }
            }, 300);
          },
          // 清除企业选择
          handleEnterpriseClear() {
            this.enterpriseOptions = [];
          },

          // 显示帮助信息
          showHelp() {
            this.$message({
              message: "绑定后可接收相关业务通知和查询项目进度",
              type: "info",
            });
          },

          // 处理手机号输入
          handlePhoneInput(value) {
            // 只保留数字
            this.formData.phone = value.replace(/[^\d]/g, "");
          },

          /**
           * 检查是否是授权回调
           */
          checkAuthorizationCallback() {
            const queryParams = this.getQueryParameters();
            // 如果URL中包含code参数，说明是授权回调
            if (queryParams.code) {
              // 回调验证
              const saveState = localStorage.getItem("wx_auth_state");
              if (saveState !== queryParams.state && saveState !== queryParams.state + '#wechat_redirect') {
                return this.$message.error("授权失败，请重新授权");
              }
              this.isAuthorizing = true;
              this.code = queryParams.code;
              localStorage.setItem("wx_auth_code", queryParams.code);
            } else if (queryParams.error) {
              // 授权失败的情况
              this.$message.error(queryParams);
              const errorMessage = `授权被拒绝: ${queryParams.error_description || queryParams.error
                }`;
              console.warn(errorMessage);
              return;
            } else {
              // 检查本地存储中是否有已保存的授权信息
              const savedCode = localStorage.getItem("wx_auth_code");
              if (savedCode) {
                this.isAuthorized = true;
                this.code = savedCode;
              } else {
                this.showAuthDialog = true;
                return;
              }
            }

            this.getUserInfo();
          },
          /**
           * 开始授权流程
           */
          startAuthorization() {
            this.isAuthorizing = true;
            // 生成随机状态值
            const state = this.generateRandomString();
            // 保存状态值到本地存储，用于回调时验证
            localStorage.setItem("wx_auth_state", state);

            // 构建授权URL
            const currentUrl = 'http://api.siisiooy.cn/wxbind';
            const authUrl = new URL(this.authConfig.authServerUrl);

            // 添加授权参数
            authUrl.searchParams.append(
              "response_type",
              this.authConfig.responseType
            );
            authUrl.searchParams.append("appid", this.authConfig.appId);
            authUrl.searchParams.append("redirect_uri", currentUrl);
            authUrl.searchParams.append("scope", this.authConfig.scope);
            authUrl.searchParams.append("state", state + "#wechat_redirect");
            console.log("redirect_uri\n", authUrl);
            // 重定向到授权服务器
            window.location.href = authUrl.toString();
          },

          /**
           * 获取URL中的查询参数
           */
          getQueryParameters() {
            const params = {};
            const queryString = window.location.search.slice(1);
            if (queryString) {
              queryString.split("&").forEach((pair) => {
                const [key, value] = pair.split("=");
                if (key) {
                  params[key] = decodeURIComponent(value || "");
                }
              });
            }
            return params;
          },

          /**
           * 生成随机字符串，用于state参数
           */
          generateRandomString(length = 32) {
            const chars =
              "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            let result = "";
            for (let i = 0; i < length; i++) {
              result += chars.charAt(Math.floor(Math.random() * chars.length));
            }
            return result;
          },

          // 获取用户信息（包括openid）- 仅在授权后调用
          getUserInfo() {
            // 实际项目中，openid通常通过后端接口获取（从微信授权后获取）
            axios
              .get("/wechat/binding-phone?code=" + this.code)
              .then((response) => {
                if (response.data.status === 200) {
                  const { nickname, headimgurl, openid, role, phone } =
                    response.data.data;
                  this.userInfo = { nickname, headimgurl, openid, phone };
                  this.formData.role = role || "";
                  this.formData.phone = phone || "";
                  if (phone) {
                    this.completeBinding = true;
                  }
                  this.isAuthorized = true;
                } else {
                  this.isAuthorized = false;
                  this.$message.error(
                    "获取用户信息失败: " + response.data.message
                  );
                }
              })
              .catch((error) => {
                console.error("获取用户信息失败:", error);
                this.isAuthorized = false;
                this.$message.error("获取用户信息失败，请重新授权");
              });
          },

          // 发送验证码
          sendVerificationCode() {
            if (!this.canSendCode) {
              this.$message.warning("请输入正确的手机号码");
              return;
            }
            if (!this.formData.role) {
              this.$message.warning("请选择用户角色");
              return;
            }

            this.isSendingCode = true;

            // 调用发送验证码接口
            axios
              .post("/api/getWxBindPhonecCode", {
                phone: this.formData.phone,
                openid: this.userInfo.openid,
                role: this.formData.role,
              })
              .then((response) => {
                if (response.data.status === 200) {
                  this.$message.success("验证码已发送，请注意查收");
                  this.startCountdown();
                } else {
                  this.$message.error("发送失败: " + response.data.message);
                  this.isSendingCode = false;
                }
              })
              .catch((error) => {
                console.error("发送验证码失败:", error);
                this.$message.error("发送验证码失败，请稍后重试");
                this.isSendingCode = false;
              });
          },

          // 验证码倒计时
          startCountdown() {
            this.codeText = `${this.countdown}s后重发`;
            const timer = setInterval(() => {
              this.countdown--;
              this.codeText = `${this.countdown}s后重发`;

              if (this.countdown <= 0) {
                clearInterval(timer);
                this.codeText = "重新发送";
                this.countdown = 60;
                this.isSendingCode = false;
              }
            }, 1000);
          },

          // 提交表单
          submitForm() {
            this.$refs.bindingForm.validate((valid) => {
              if (valid) {
                this.isSubmitting = true;

                // 准备提交的数据，包含openid
                const submitData = {
                  ...this.formData,
                  openid: this.userInfo.openid,
                };

                // 调用绑定接口
                axios
                  .post("/api/bind-account", submitData)
                  .then((response) => {
                    if (response.data.status === 200) {
                      this.$message.success("账号绑定成功！");
                      this.completeBinding = true;
                    } else {
                      this.$message.error("绑定失败: " + response.data.message);
                    }
                  })
                  .catch((error) => {
                    console.error("绑定账号失败:", error);
                    this.$message.error("绑定失败，请稍后重试");
                  })
                  .finally(() => {
                    this.isSubmitting = false;
                  });
              }
            });
          },
        },
      });
    </script>
  </body>

</html>